#include "sinks/network_sink.hpp"
#include <iostream>
#include <vector>


static std::once_flag curl_init_flag;
static std::once_flag curl_cleanup_flag;
CurlGlobalManager NetworkSink::m_curl_manager;

// 静态回调函数实现
size_t NetworkSink::write_callback(void* contexts, size_t size, size_t nmemb, void* userp) {
    (void)contexts;   // 忽略响应内容
    (void)userp;
    return size * nmemb;
}


NetworkSink::NetworkSink(const std::string& url, size_t thread_pool_size, long timeout, long connect_timeout) 
    : m_url(url)
    , m_thread_pool(thread_pool_size)
    , m_threadPoolSize(thread_pool_size)
    , m_timeout(timeout)
    , m_connect_timeout(connect_timeout) {

    // 无需手动创建句柄（CurlHandle构造函数已初始化）
    if (!m_curHandle) {  // 通过operator bool()判断句柄是否有效
        throw std::runtime_error("Error: Failed to create curl handle.");
    }

    // 配置curl参数（失败时无需手动清理，RAII类析构会自动释放）
    if (!configureCurl()) {
        throw std::runtime_error("Error: Failed to configure curl for NetworkSink.");
    }
}    

bool NetworkSink::configureCurl() {
    CURL* handle = m_curHandle.get();  // 获取原生句柄
    CURLcode res;
    res = curl_easy_setopt(handle, CURLOPT_URL, m_url.c_str());
    if (res != CURLE_OK) {
        std::cerr << "curl_easy_setopt(URL) failed: " << curl_easy_strerror(res) << std::endl;
        return false;
    }
    res = curl_easy_setopt(handle, CURLOPT_POST, 1L);
    res = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
    res = curl_easy_setopt(handle, CURLOPT_WRITEDATA, nullptr);
    res = curl_easy_setopt(handle, CURLOPT_TIMEOUT, m_timeout);
    res = curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, m_connect_timeout);
    // 使用CurlSlist的append方法添加头信息
    m_headers.append("Content-Type: application/json");
    res = curl_easy_setopt(handle, CURLOPT_HTTPHEADER, m_headers.get());
    if (res != CURLE_OK) {
        std::cerr << "curl_easy_setopt(HTTPHEADER) failed: " << curl_easy_strerror(res) << std::endl;
        return false;
    }
    return true;
}


void NetworkSink::log(LogLevel level, const std::string& formatted_message) {
    if (!m_curHandle) {  // 句柄无效时直接返回
        std::cerr << "NetworkSink is not initialized. Log dropped." << std::endl;
        return;
    }
    m_thread_pool.enqueue([this, msg = formatted_message]() {
        std::lock_guard<std::mutex> lock(m_curlMutex);
        CURL* handle = m_curHandle.get();
        curl_easy_setopt(handle, CURLOPT_POSTFIELDS, msg.c_str());
        curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, msg.size());
        // 带重试逻辑（同上，省略）
        CURLcode res = curl_easy_perform(handle);
        if (res != CURLE_OK) {
            std::cerr << "Error sending log: " << curl_easy_strerror(res) << std::endl;
        }
    });
}

